package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"

	"github.com/gin-gonic/gin"

	"github.com/kardianos/service"
)

type program struct{}

func (p *program) Start(s service.Service) error {
	go p.run()
	return nil
}

func (p *program) run() {
	beginHTTPServer()
}

func (p *program) Stop(s service.Service) error {
	//monitor.KillAll()
	return nil
}

func init() {

}

func getPWD() string {
	ex, _ := os.Executable()
	pwd := filepath.Dir(ex)
	fmt.Println("------------", pwd)
	return pwd
}

//ErrorStruct 错误结构
type ErrorStruct struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

type playVideo struct {
	Addr string
}

//Cors 跨域
func Cors() gin.HandlerFunc {
	return func(c *gin.Context) {
		method := c.Request.Method
		if c.Request.URL == nil || len(method) < 3 {
			return
		}
		//method := c.Request.Method               //请求方法
		origin := c.Request.Header.Get("Origin") //请求头部

		if origin != "" {
			c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
			c.Request.Header.Del("Origin")
		} else {
			c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
		}
		c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
		c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,X_Requested_With,Accept, Origin, Host, Connection, Accept-Encoding, Accept-Language,DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Pragma,api_token")
		//c.Writer.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type, Content-Length, X-CSRF-Token, Token, session, Origin, Host, Connection, Accept-Encoding, Accept-Language, X-Requested-With")

		c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,X_Requested_With,Accept, Origin, Host, Connection, Accept-Encoding, Accept-Language,DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Pragma,api_token")
		c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,FooBar") // 跨域关键设置 让浏览器可以解析
		c.Header("Access-Control-Max-Age", "172800")                                                                                                                                                           // 缓存请求信息 单位为秒
		//c.Header("Access-Control-Allow-Credentials", "false")                                                                                                                                                  //  跨域请求是否需要带cookie信息 默认设置为true
		c.Set("content-type", "application/json") // 设置默认返回格式是json
		if c.Request.Method == "OPTIONS" {
			c.JSON(http.StatusOK, "Options Request!")
			return
		}

		//放行所有OPTIONS方法 原因为当Request Header中存在自定义的key时，浏览器会首先发送一个options请求，判断后端是否支持，只有返回状态码为200时，才会真正发送请求
		// 处理请求
		c.Next()
	}
}

func SendResultEx(result interface{}, err error, errCode int, c *gin.Context) {
	if err != nil || errCode != 0 {

		errstruct := ErrorStruct{
			Code:    errCode,
			Message: err.Error(),
		}
		c.JSON(http.StatusOK, gin.H{
			"error": errstruct,
		})
	} else {
		c.JSON(http.StatusOK, gin.H{
			"result": result,
		})
	}
}

func beginHTTPServer() {
	r := gin.Default()
	r.Use(Cors())
	r.PUT("/playVideo", func(c *gin.Context) {
		var info playVideo
		err := c.ShouldBindJSON(&info)
		if err == nil {
			pwd := getPWD()
			if pwd != "" {
				pwd = pwd + "\\VLCPortable\\"
				cmd := exec.Command("cmd", "/c", "start", "/B", pwd+"vlc.exe", info.Addr)
				if err = cmd.Start(); err != nil {
					//utils.ErrInfo(err.Error())
					fmt.Println("err--------", err)
				}

			}
		}
		SendResultEx("OK", err, 0, c)
	})
	r.GET("/playVideo", func(c *gin.Context) {
		SendResultEx("OK", nil, 0, c)
	})
	r.Run(":18869")
}

func main() {
	svcConfig := &service.Config{
		Name:        "VideoPService",
		DisplayName: "VideoPService",
		Description: "windows service for VideoPService",
	}

	prg := &program{}
	s, _ := service.New(prg, svcConfig)

	if len(os.Args) > 1 {
		fmt.Println("-------------*************------", os.Args[1])
		if os.Args[1] == "install" {
			//s.Install()
			s.Uninstall()
			cmd := exec.Command("sc", "create", "VideoPService", `binPath= "`+getPWD()+"/vpsc.exe"+`"`, "start=auto")
			out, _ := cmd.CombinedOutput()
			log.Println("服务安装", string(out))
			cmdr := exec.Command("sc", "start", "VideoPService")
			cmdr.Run()
			return

		}

		if os.Args[1] == "remove" {
			//monitor.KillAll()
			cmdr := exec.Command("sc", "stop", "VideoPService")
			cmdr.Run()
			s.Uninstall()
			log.Println("服务卸载成功")

		}
		return
	}
	if err := s.Run(); err != nil {
		log.Panicln(err)
	}

}
